<template>
  <el-button
    :ref="getButtonRef"
    link
    type="primary"
    :style="{ color: !fieldData.isCondition ? '#909399' : '' }"
    v-click-outside="onClickOutside"
  >
    <span style="display: inline-block; margin-right: 10px">{{ fieldData.title }}</span>
    <el-icon v-show="fieldData.isFilter"><Filter /></el-icon>
  </el-button>

  <el-popover
    :placement="placement"
    ref="popoverRef"
    :virtual-ref="buttonRef"
    trigger="click"
    virtual-triggering
    :width="500"
    @show="handelOpenFilter"
    @hide="handelHideFilter"
  >
    <div class="filter-table-header">
      <div class="condition">
        <el-select
          style="width: 150px; margin-right: 10px"
          placeholder="请选择"
          :teleported="false"
          v-model="fieldData.compare"
          @change="initFilter"
        >
          <el-option
            v-for="(typeItem, index) in conditionTypes[fieldData.fieldName]"
            :key="`${typeItem.value}${index}`"
            :label="typeItem.label"
            :value="typeItem.value"
          ></el-option>
        </el-select>
        <!--     TODO:动态渲染   -->
        <template v-if="fieldData.fieldName === 'NumberInput'">
          <el-input
            v-if="inputCompare.includes(fieldData.compare)"
            style="width: 300px"
            :disabled="['isNull', 'isNotNull'].includes(fieldData.compare)"
            v-model.number="fieldData.value[0]"
            placeholder="请输入"
            clearable
          />
          <div v-if="rangeCompare.includes(fieldData.compare)" style="display: inline-block; margin-top: 10px">
            <el-input
              style="width: 150px; margin-right: 10px"
              v-model.number="fieldData.value[0]"
              placeholder="请输入"
              clearable
            />
            <el-input style="width: 150px" v-model.number="fieldData.value[1]" placeholder="请输入" clearable />
          </div>
        </template>

        <template v-if="fieldData.fieldName === 'TextInput'">
          <el-input
            style="width: 300px"
            v-if="textCompare.includes(fieldData.compare)"
            :disabled="['isNull', 'isNotNull'].includes(fieldData.compare)"
            v-model="fieldData.value[0]"
            placeholder="请输入"
            clearable
          />
          <el-select
            style="width: 300px"
            v-if="textCompareRange.includes(fieldData.compare)"
            :teleported="false"
            multiple
            filterable
            allow-create
            default-first-option
            collapse-tags-tooltip
            :reserve-keyword="false"
            collapse-tags
            :max-collapse-tags="1"
            v-model="fieldData.value"
          >
            <el-option v-for="textItem in fieldData.value" :label="textItem" :value="textItem"></el-option>
          </el-select>
        </template>

        <template v-if="fieldData.fieldName === 'DateTime'">
          <el-date-picker
            style="width: 300px"
            v-if="['EQ', 'isNull', 'isNotNull'].includes(fieldData.compare)"
            v-model="fieldData.value[0]"
            :teleported="false"
            :disabled="['isNull', 'isNotNull'].includes(fieldData.compare)"
            type="date"
            value-format="YYYY-MM-DD"
            format="YYYY-MM-DD"
            date-format="YYYY-MM-DD"
          />
          <el-date-picker
            style="margin-top: 10px"
            v-if="fieldData.compare === 'Between'"
            v-model="fieldData.value"
            :teleported="false"
            type="daterange"
            value-format="YYYY-MM-DD"
            format="YYYY-MM-DD"
            date-format="YYYY-MM-DD"
            range-separator="-"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
          />
          <el-select style="width: 225px" :teleported="false" v-model="fieldData.value[0]" v-if="fieldData.compare === 'Dynamic'">
            <el-option v-for="selectItem in dynamicOptions" :label="selectItem.label" :value="selectItem.value"></el-option>
          </el-select>
        </template>

        <template v-if="fieldData.fieldName === 'SelectInput'">
          <el-select
            style="width: 300px"
            :teleported="false"
            v-model="fieldData.value[0]"
            :disabled="['isNull', 'isNotNull'].includes(fieldData.compare)"
          >
            <el-option v-for="selectItem in fieldData.options" :label="selectItem.label" :value="selectItem.value"></el-option>
          </el-select>
        </template>

        <template v-if="fieldData.fieldName === 'MultipleSelect'">
          <el-select
            style="width: 300px"
            :teleported="false"
            multiple
            v-model="fieldData.value"
            allow-create
            default-first-option
            collapse-tags-tooltip
            :reserve-keyword="false"
            collapse-tags
            :max-collapse-tags="1"
            :disabled="['isNull', 'isNotNull'].includes(fieldData.compare)"
          >
            <el-option
              v-for="selectItem in fieldData.options"
              :label="selectItem.labelConcat || selectItem.label"
              :value="selectItem.value"
            ></el-option>
          </el-select>
        </template>

        <template v-if="fieldData.fieldName === 'CascaderInput'">
          <el-cascader
            style="width: 300px"
            :teleported="false"
            :props="{
              label: 'name',
              value: 'cityCode'
            }"
            v-model="fieldData.value"
            :disabled="['isNull', 'isNotNull'].includes(fieldData.compare)"
            clearable
            :options="cascaderOptions"
          ></el-cascader>
        </template>

        <template v-if="fieldData.fieldName === 'UserPicker'">
          <el-input
            style="width: 300px"
            v-if="userCompare.includes(fieldData.compare)"
            v-model="fieldData.value[0]"
            placeholder="请输入"
            clearable
          />
        </template>
      </div>

      <div class="filter-buttons">
        <el-button @click="handelReset" type="primary" link size="default">重置</el-button>
        <el-button @click="handelConfirm" type="primary" size="default">确定</el-button>
      </div>
    </div>
  </el-popover>
</template>

<script setup>
import { ref, unref, nextTick, computed } from "vue";
import { ClickOutside as vClickOutside } from "element-plus";
import { Filter } from "@element-plus/icons-vue";
import _ from "lodash";
import { selectDictDataByType, dictList } from "@/apis/dict/dict";
import { nonDictData } from "@/apis/clientManager";
import cascaderOptions from "@/assets/pca-code";
import {
  conditionTypes,
  textCompare,
  textCompareRange,
  inputCompare,
  rangeCompare,
  dynamicOptions,
  userCompare
} from "../../config";
import config from "@/settings";

const props = defineProps({
  tableHeaderData: {
    type: Object,
    default: () => ({})
  },
  columnIndex: {
    type: Number,
    default: 0
  }
});
const emit = defineEmits(["handelFilterData"]);

const placement = computed(() => {
  return props.tableHeaderData.fieldId === "customer_name" ? "right" : "bottom";
});

const isClickOutside = ref(false);
const isGroupLoading = ref(false);
const fieldData = ref(_.cloneDeep(props.tableHeaderData));
fieldData.value.fieldName === "SelectInput" && (fieldData.value.value = [""]);

const dictTypes = [config.dicts.COSTEM_PREPRICE, config.dicts.COSTEM_ORIGIN];
const getDboDict = async ({ sourceValue, fieldData }) => {
  try {
    isGroupLoading.value = true;
    const { data } = await selectDictDataByType(sourceValue);
    const dictData = data || [];
    fieldData.options = dictData.map(item => ({
      label: item.dictLabel,
      value: item.dictValue
    }));
    isGroupLoading.value = false;
  } catch (err) {
    isGroupLoading.value = false;
  }
};
const getSaasDict = async ({ sourceValue, fieldData }) => {
  try {
    isGroupLoading.value = true;
    const { data } = await dictList({ dictType: sourceValue });
    const dictData = data || [];
    fieldData.options = dictData.map(item => ({
      labelConcat: dictTypes.includes(sourceValue) ? `${item.dictLabel}(${item.dictValue})` : item.dictLabel,
      label: item.dictLabel,
      value: item.dictCode
    }));
    isGroupLoading.value = false;
  } catch (err) {
    isGroupLoading.value = false;
  }
};
const getSelectOption = ({ fieldData, options }) => {
  fieldData.options =
    options?.map(item => ({
      label: typeof item === "number" ? (item === 0 ? "否" : "是") : item,
      value: item
    })) || [];
};
const getRemoteData = async ({ sourceValue, fieldData }) => {
  try {
    isGroupLoading.value = true;
    const { data } = await nonDictData({ method: sourceValue });
    const dictData = data || [];
    let optionData = _.cloneDeep(dictData);
    if (sourceValue === "crmPortraitService.pageList()") {
      optionData = dictData.map(item => ({
        label: item.portraitName,
        value: item.portraitId
      }));
    }
    fieldData.options = optionData;
    isGroupLoading.value = false;
  } catch (err) {
    isGroupLoading.value = false;
  }
};
const sourceTypes = new Map([
  ["dbo:dict", getDboDict],
  ["sass:dict", getSaasDict],
  ["select", getSelectOption],
  ["remote", getRemoteData]
]);
const getDataSource = () => {
  const { props } = fieldData.value;
  const { sourceType, sourceValue, options } = props && JSON.parse(props);
  sourceTypes.has(sourceType)
    ? sourceTypes.get(sourceType)({ fieldData: fieldData.value, sourceValue, options })
    : (fieldData.value.options = []);
};

const initFilter = val => {
  if (["DateTime", "TextInput"].includes(fieldData.value.fieldName)) {
    fieldData.value.value = [""];
  }
  if (fieldData.value.fieldName === "NumberInput") {
    fieldData.value.value = [0];
  }
  if (["MultipleSelect", "SelectInput"].includes(fieldData.value.fieldName)) {
    fieldData.value.compare = val || "IN";
    fieldData.value.value = [];
    fieldData.value.fieldName === "SelectInput" && (fieldData.value.value = [""]);
    getDataSource();
  }
  if (fieldData.value.fieldName === "UserPicker") {
    fieldData.value.compare = "LIKE";
    fieldData.value.value = [""];
  }
  if (!fieldData.value.compare) {
    fieldData.value.compare = "EQ";
  }
};

const handelOpenFilter = () => {
  if (fieldData.value.compare) {
    fieldData.value.fieldName === "CascaderInput" &&
      fieldData.value.value?.length &&
      (fieldData.value.value = fieldData.value.value[0].split(","));
    return;
  }
  initFilter();
};
const handelHideFilter = () => {
  if (isClickOutside.value) {
    fieldData.value = _.cloneDeep(props.tableHeaderData);
    fieldData.value.fieldName === "SelectInput" && !fieldData.value.value?.length && (fieldData.value.value = [""]);
    emit("handelFilterData", { fieldData: props.tableHeaderData, columnIndex: props.columnIndex, isRefresh: false });
  }
};
const handelConfirm = () => {
  if (fieldData.value.fieldName === "CascaderInput" && fieldData.value.value) {
    fieldData.value.value = [fieldData.value.value.join(",")];
  }
  fieldData.value.isCondition = true;
  const cloneFieldData = _.cloneDeep(fieldData.value);
  if (cloneFieldData.compare === "isNull") {
    cloneFieldData.value = ["isNull"];
  }
  if (cloneFieldData.compare === "isNotNull") {
    cloneFieldData.value = ["isNotNull"];
  }
  emit("handelFilterData", { fieldData: cloneFieldData, columnIndex: props.columnIndex, isRefresh: true });
  isClickOutside.value = false;
  popoverRef.value.hide();
};
const handelReset = () => {
  fieldData.value.compare = "";
  fieldData.value.value = [];
  fieldData.value.isCondition = false;
  emit("handelFilterData", { fieldData: fieldData.value, columnIndex: props.columnIndex, isRefresh: true });
  isClickOutside.value = false;
  popoverRef.value.hide();
};

const buttonRef = ref(null);
const popoverRef = ref(null);
const getButtonRef = e => {
  if (fieldData.value.isFilter) {
    buttonRef.value = e;
  }
};
const onClickOutside = async () => {
  await nextTick();
  if (!fieldData.value.isFilter) return;
  isClickOutside.value = true;
  unref(popoverRef).popperRef?.delayHide?.();
};
</script>
<style scoped lang="scss">
@use "@/assets/styles/mixin";
:deep(.el-input__wrapper),
:deep(.el-select__wrapper),
:deep(.el-textarea__inner),
:deep(.el-input__count),
:deep(.el-input__count-inner) {
  background-color: #f2f3f5 !important;
}
.filter-table-header {
  .condition {
    padding: 12px;
    box-sizing: border-box;
    border-bottom: 1px solid #d7d8e0;
  }
  .filter-buttons {
    @include mixin.flex-center;
    padding: 12px;
    box-sizing: border-box;
    :deep(.el-button) {
      width: 130px;
      height: 28px;
    }
  }
}
.filter-icon-active {
  padding: 3px;
  border-radius: 2px;
  background-color: #e7eaf0;
}
</style>
